package com.sduept.nwld.dataserver.controller.assessment;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;

import org.primefaces.event.NodeExpandEvent;
import org.primefaces.event.NodeSelectEvent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.fastjson.JSONArray;
import com.sduept.bigdata.fault.dto.ComponetActionIntervalDTO;
import com.sduept.bigdata.fault.protection.service.ComponetActionInfoQueryManager;
import com.sduept.bigdata.web.jsf.controller.AbstractController;
import com.sduept.nwld.dataserver.util.LibTreeNode;
import com.sduept.utils.DateUtil;

/**
 * 断路器动作过程分析
 * 
 * @author Ningfw
 * @date 2017-11-13
 * 
 */

@Named
@ViewScoped
public class BreakerWaveProcessController extends AbstractController {
	/**
	 * 
	 */
	private static final long serialVersionUID = 6976116361278380094L;
	@Autowired
	private ComponetActionInfoQueryManager caiqm;

	private TreeNode root;
	private TreeNode currentSelect;
	private String chartData;
	private String currentNodeType="nwzd";
	private List<ComponetActionIntervalDTO> actionIntervalList;
	@PostConstruct
	private void init() {
		int year = Calendar.getInstance().get(Calendar.YEAR);
		try{
			Date start = DateUtil.getDateByString(year+"-01-01", DateUtil.pattern_ymd);
			Date end = DateUtil.getDateByString(year+"-12-31", DateUtil.pattern_ymd);
			actionIntervalList =  caiqm.getComponetActionIntervalDTOByDate(start, end);
		}catch(Exception e){e.printStackTrace();}
		initTree();
		chartData=initChartData(actionIntervalList);
	}

	public void refresh() {
		initTree();
	}

	/**
	 * 初始化数据 默认展开 变电站
	 */
	public void initTree() {
		root = new DefaultTreeNode();
		LibTreeNode firstNode= new LibTreeNode("nwzd", "南网总调", root);
		List<String> stations = new ArrayList<String>();
		for (ComponetActionIntervalDTO sub : actionIntervalList) {
			if(!stations.contains(sub.getStationName())){
				stations.add(sub.getStationName());
			}
		}
		for(String station:stations){
			new LibTreeNode("station", station, firstNode);
		}
		firstNode.setExpanded(true);
		firstNode.setSelected(true);
	}


	public void onNodeExpand(NodeExpandEvent event) {// 点击
		Set<String> result = new HashSet<String>();
		TreeNode currentNode = event.getTreeNode();
		if("station".equals(currentNode.getType())){
			for (ComponetActionIntervalDTO sub : actionIntervalList) {
				if(currentNode.getData().equals(sub.getStationName())
						&& !result.contains(sub.getBreakerName())){
					result.add(sub.getBreakerName());
				}
			}
			for(String r:result){
				new LibTreeNode("breaker", r, currentNode);
			}
		}else if("breaker".equals(currentNode.getType())){
			for (ComponetActionIntervalDTO sub : actionIntervalList) {
				if(currentNode.getParent().getData().equals(sub.getStationName())
						&& currentNode.getData().equals(sub.getBreakerName())){
					result.add(sub.getPhase());
				}
			}
			for(String r:result){
				new LibTreeNode("phase", r, currentNode);
			}
		}else if("phase".equals(currentNode.getType())){
			for (ComponetActionIntervalDTO sub : actionIntervalList) {
				if(currentNode.getParent().getParent().getData().equals(sub.getStationName())
						&& currentNode.getParent().getData().equals(sub.getBreakerName())
						&& currentNode.getData().equals(sub.getPhase())){
					result.add(sub.getFaultDate());
				}
			}
			List<String> newList=sortSetByDate(result);
			for(String r:newList){
				new DefaultTreeNode("faultDate", r, currentNode);
			}
		}
	}
	/**
	 * 对时间set集合按时间降序排列
	 * @param dateSet
	 */
	private List<String> sortSetByDate(Set<String> dateSet) {
		List<String> newDateList=new ArrayList<>(dateSet);
		Collections.sort(newDateList, new Comparator<String>() {
			@Override
			public int compare(String o1, String o2) {
				Date date1=DateUtil.getDateByString(o1, DateUtil.pattern_ymdhms);
				Date date2=DateUtil.getDateByString(o2, DateUtil.pattern_ymdhms);
				if(date1.before(date2)) {
					return 1;
				}else if(date1.after(date2)) {
					return -1;
				}else {
					return 0;
				}
			}
			
		});
		return newDateList;
	}
	// 事件
	public void onNodeSelect(NodeSelectEvent event) {// 选择
		List<ComponetActionIntervalDTO> result = new ArrayList<ComponetActionIntervalDTO>();
		TreeNode currentNode = event.getTreeNode();
		currentNodeType=currentNode.getType();
		if("nwzd".equals(currentNodeType)){
			for (ComponetActionIntervalDTO sub : actionIntervalList) {
				result.add(sub);
			}
		}else if("station".equals(currentNodeType)){
			for (ComponetActionIntervalDTO sub : actionIntervalList) {
				if(currentNode.getData().equals(sub.getStationName())){
					result.add(sub);
				}
			}
		}else if("breaker".equals(currentNodeType)){
			for (ComponetActionIntervalDTO sub : actionIntervalList) {
				if(currentNode.getParent().getData().equals(sub.getStationName())
						&& currentNode.getData().equals(sub.getBreakerName())){
					result.add(sub);
				}
			}
		}else if("phase".equals(currentNodeType)){
			for (ComponetActionIntervalDTO sub : actionIntervalList) {
				if(currentNode.getParent().getParent().getData().equals(sub.getStationName())
						&& currentNode.getParent().getData().equals(sub.getBreakerName())
						&& currentNode.getData().equals(sub.getPhase())){
					result.add(sub);
				}
			}
		}else if("faultDate".equals(currentNodeType)){
			for (ComponetActionIntervalDTO sub : actionIntervalList) {
				if(currentNode.getParent().getParent().getParent().getData().equals(sub.getStationName())
						&& currentNode.getParent().getParent().getData().equals(sub.getBreakerName())
						&& currentNode.getParent().getData().equals(sub.getPhase())
						&& currentNode.getData().equals(sub.getFaultDate())){
					result.add(sub);
				}
			}
		}
		chartData=initChartData(result);
	}
	//组织chart数据
	private double avg1;
	private double avg2;
	private double avg3;
	private double avg4;
	private double avg5;
	private double avg6;
    private String initChartData(List<ComponetActionIntervalDTO> com){
       calAverage(com);//先计算六组均值
	   JSONArray jso=new JSONArray();
	   List<String[]> zbhDlqbbhInterval=new ArrayList<>();// 主保护到断路器保护的间隔
	   List<String[]> zbhCzxInterval=new ArrayList<>();// 主保护到操作箱的间隔
	   List<String[]> czxdlqTwInterval=new ArrayList<>();// 操作箱发跳到断路器跳位间隔
	   List<String[]> czxdlqHwInterval=new ArrayList<>();// 操作箱保护发跳到断路器合位间隔
	   List<String[]> chzDlqRevertTw=new ArrayList<>();// 重合闸到断路器跳位恢复间隔
	   List<String[]> chzDlqRevertHw=new ArrayList<>();// 重合闸到断路器合位恢复间隔
	   for(int i=1;i<=com.size();i++){
		   ComponetActionIntervalDTO ca=com.get(i-1);
		   if(ca.getZbhDlqbbhInterval()!=0&&ca.getZbhDlqbbhInterval()<=100000){
			   zbhDlqbbhInterval.add(getChartData(ca.getZbhDlqbbhInterval(),Math.random()*360,ca,avg1));
		   }
		   if(ca.getZbhCzxInterval()!=0&&ca.getZbhCzxInterval()<=100000){
			   zbhCzxInterval.add(getChartData(ca.getZbhCzxInterval(),Math.random()*360,ca,avg2));
		   }
		   if(ca.getCzxdlqTwInterval()!=0&&ca.getCzxdlqTwInterval()<=100000){
			   czxdlqTwInterval.add(getChartData(ca.getCzxdlqTwInterval(),Math.random()*360,ca,avg3));
		   }
		   if(ca.getCzxdlqHwInterval()!=0&&ca.getCzxdlqHwInterval()<=100000){
			   czxdlqHwInterval.add(getChartData(ca.getCzxdlqHwInterval(),Math.random()*360,ca,avg4));
		   }
		   if(ca.getChzDlqRevertTw()!=0&&ca.getChzDlqRevertTw()<=100000){
			   chzDlqRevertTw.add(getChartData(ca.getChzDlqRevertTw(),Math.random()*360,ca,avg5));
		   }
		   if(ca.getChzDlqRevertHw()!=0&&ca.getChzDlqRevertHw()<=100000){
			   chzDlqRevertHw.add(getChartData(ca.getChzDlqRevertHw(),Math.random()*360,ca,avg6));
		   }
	   }
	   jso.add(zbhCzxInterval);
	   jso.add(zbhDlqbbhInterval);
	   jso.add(czxdlqHwInterval);
	   jso.add(czxdlqTwInterval);
	   jso.add(chzDlqRevertHw);
	   jso.add(chzDlqRevertTw);
	   return jso.toString();
    }
    //每个点
    private String[] getChartData(long data,double degree,ComponetActionIntervalDTO ca,double avg){
    	 DecimalFormat df=new DecimalFormat("#0.0");
    	 String[]  result=new String[9];
    	 result[0]=df.format(data/1000);//时间
    	 result[1]=String.valueOf(degree);//角度
    	 result[2]=ca.getFaultDate();//故障时间
    	 result[3]=ca.getStationName();//站点
    	 result[4]=ca.getBreakerName();//断路器
    	 result[5]=ca.getLineName();//线路
    	 result[6]=ca.getPhase();//相别
    	 result[7]=df.format(avg/1000);//均值
    	 result[8]=df.format((Math.abs(1-data/avg)));//偏差
		 return result;
    }
    //给每个点算偏差和均值
    private void calAverage(List<ComponetActionIntervalDTO> com){
    	int totalNum1=0;//总数
    	double sum1=0; 
    	int totalNum2=0;//总数
    	double sum2=0; 
    	int totalNum3=0;//总数
    	double sum3=0; 
    	int totalNum4=0;//总数
    	double sum4=0; 
    	int totalNum5=0;//总数
    	double sum5=0; 
    	int totalNum6=0;//总数
    	double sum6=0; 
    	for(int i=0;i<com.size();i++){
 		   ComponetActionIntervalDTO ca=com.get(i);
 		   if(ca.getZbhDlqbbhInterval()!=0){
 			  totalNum1++;
 			  sum1+=ca.getZbhDlqbbhInterval();
 		   }
 		   if(ca.getZbhCzxInterval()!=0){
 			  totalNum2++;
 			  sum2+=ca.getZbhCzxInterval();
 		   }
 		   if(ca.getCzxdlqTwInterval()!=0){
 			  totalNum3++;
 			  sum3+=ca.getCzxdlqTwInterval();
 		   }
 		   if(ca.getCzxdlqHwInterval()!=0){
 			  totalNum4++;
 			  sum4+=ca.getCzxdlqHwInterval();
 		   }
 		   if(ca.getChzDlqRevertTw()!=0){
 			  totalNum5++;
 			  sum5+=ca.getChzDlqRevertTw();
 		   }
 		   if(ca.getChzDlqRevertHw()!=0){
 			  totalNum6++;
 			  sum6+=ca.getChzDlqRevertHw();
 		   }
 	   }
    	avg1=sum1/totalNum1;
    	avg2=sum2/totalNum2;
    	avg3=sum3/totalNum3;
    	avg4=sum4/totalNum4;
    	avg5=sum5/totalNum5;
    	avg6=sum6/totalNum6;
    }
	public TreeNode getRoot() {
		return root;
	}
	public void setRoot(TreeNode root) {
		this.root = root;
	}
	public String getChartData() {
		return chartData;
	}
	public void setChartData(String chartData) {
		this.chartData = chartData;
	}
	public TreeNode getCurrentSelect() {
		return currentSelect;
	}

	public String getCurrentNodeType() {
		return currentNodeType;
	}

	public void setCurrentNodeType(String currentNodeType) {
		this.currentNodeType = currentNodeType;
	}
}
